import { ElMessageBox } from 'element-plus'
import { io } from 'socket.io-client'
import Nprogress from 'nprogress'
import localCache from '@/utils/cache.js'
import router from '@/router/index.js'
import { binMsg } from '@/global/api.js'
import {
  userLogin,
  getMenusByRole,
  updateAvatar,
  getUserById,
  updateUserInfo,
  uploadAvatar
} from '@/services/roleCommon.js'
import { getNewNotices } from '@/services/notices.js'
import { mapMenusToRoutes } from '@/utils/mapMenus.js'

// const socket = io('ws://localhost:8081')
const userModule = {
  // 开启命名空间
  namespaced: true,
  state() {
    return {
      userInfo: {}, // 用户信息
      userMenus: [], // 用户菜单
      socket: null
    }
  },

  mutations: {
    // 仅用于第一次用户登录时，保存用户信息并触发socket上线事件
    changeUserInfo(state, userInfo) {
      state.userInfo = userInfo
      state.socket = io('ws://localhost:8888')
      state.socket.emit('online', userInfo.id)
    },
    // 清空
    clearUserInfo(state) {
      state.userInfo = null
      state.socket = null
      state.userMenus = null
    },
    // 更新用户菜单
    changeUserMenus(state, userMenus) {
      state.userMenus = userMenus
      // userMenus => routes，调用函数
      const routes = mapMenusToRoutes(userMenus)
      // console.log(routes)
      // 将 routes => router.home.children
      // 将获取到的每一个 chilren 添加到 home 路由的子路由
      routes.forEach((route) => {
        router.addRoute('Home', route)
      })
    },

    // 更新用户信息数据并保存到本地
    change2UserInfo(state, userInfo) {
      state.userInfo = userInfo
      localCache.setCache('userInfo', userInfo)
    }
  },

  actions: {
    //TODO 登录 -> 用户信息存至 store和本地 -> 请求用户菜单保存到 store和本地
    async loginAction(context, payload) {
      try {
        //TODO 发起登录请求
        const { data: loginRes } = await userLogin(payload.role, payload.accountForm)
        if (loginRes.meta.status === 400) return binMsg('error', loginRes.meta.msg)

        context.commit('changeUserInfo', loginRes.data.userInfo) // 保存至state
        localCache.setCache('token', loginRes.data.token) // 将token保存到session
        localCache.setCache('userInfo', loginRes.data.userInfo) // 将用户信息保存到session

        // console.log(loginRes);

        //TODO 发起获取菜单请求（根据用户 role 获取对应菜单）
        const { data: menuRes } = await getMenusByRole(loginRes.data.userInfo.role)
        if (menuRes.meta.status === 400) return binMsg('error', menuRes.meta.msg)

        // console.log(menuRes.data.data.menus);
        context.commit('changeUserMenus', menuRes.data.data.menus)
        localCache.setCache('userMenus', menuRes.data.data.menus) // 将token保存到session

        //TODO 跳转到首页
        router.push('/home')
        binMsg('success', '登录成功！')
      } catch (error) {
        Nprogress.done()
        return binMsg('error', '请检查网络或者服务！')
      }
    },

    //TODO 本地缓存登录时的数据后，如果用户刷新了页面，会调用这个方法，将本地缓存的数据赋值给 vuex store 中
    loadLocalLoginAction({ commit, dispatch }) {
      const userInfo = localCache.getCache('userInfo')
      const userMenus = localCache.getCache('userMenus')
      if (userInfo) commit('changeUserInfo', userInfo)
      if (userMenus) commit('changeUserMenus', userMenus)
    },

    //TODO 退出登录 -> 清空 store 和本地数据
    async logOutAction({ commit, state }) {
      try {
        await ElMessageBox.confirm('此操作将会退出登录！', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          draggable: true
        })
        // socket服务下线，在后端删除对应用户
        state.socket.emit('offline', state.userInfo.id)

        // 清空所有store中的数据，包括其他模块的store数据
        // commit('clearUserInfo')
        commit('changeUserMenus', [])
        commit('tagsViewModule/changeTagsView', [], { root: true })
        commit('friendModule/changefriendList', [], { root: true })
        commit('messageModule/changeMessage', [], { root: true })
        commit('userManageModule/clearState', [], { root: true })
        commit('lessonManageModule/clearState', [], { root: true })
        commit('collegeManageModule/clearState', [], { root: true })
        commit('noticesManageModule/clearState', [], { root: true })
        commit('selectCourseModule/clearState', [], { root: true })
        localCache.clearCache() // 清空缓存
        router.replace('/login')
        binMsg('success', '退出成功！')
      } catch (e) {
        binMsg('info', '已取消')
      }
    },

    // TODO 修改用户信息
    async updateInfoAction({ commit }, payload) {
      const { data: res } = await updateUserInfo(payload.role, payload.infoForm)
      if (res.meta.status !== 200) return binMsg('error', res.meta.msg)
      // 重新保存用户信息数据
      commit('change2UserInfo', res.data.data)
      localCache.setCache('userInfo', res.data.data)
      binMsg('success', res.meta.msg)
    },

    // TODO 上传用户头像 -> 请求最新用户信息
    async uploadUserAvatar({ state, commit, dispatch }, payload) {
      // 发起上传图片的请求
      const { data: res } = await uploadAvatar(payload.role, payload.formData)
      if (res.meta.status === 200) {
        binMsg('success', res.meta.msg)
        // 图片上传成功后，重新获取用户数据
        dispatch('getUserInfoAction', { role: payload.role, id: state.userInfo.id })
      }
    },

    //TODO 更新用户头像（base64，已废弃）
    async updateAvatarAction({ commit, dispatch }, payload) {
      const { data: res } = await updateAvatar(payload.role, payload.uploadForm)
      if (res.meta.status !== 200) return binMsg('error', res.meta.msg)
      // 重新获取用户信息
      dispatch('getUserInfoAction', { role: payload.role, id: payload.uploadForm.id })
      binMsg('success', res.meta.msg)
    },

    //* 获取用户信息 -> 保存到 store 和本地
    async getUserInfoAction({ commit }, payload) {
      const { data: res } = await getUserById(payload.role, payload.id)
      // 将用户信息保存到 store和本地
      commit('change2UserInfo', res.data.data)
    }
  }
}

export default userModule
